package com.dragon.modules.yuegou.service.impl.system;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dragon.common.exception.DragonException;
import com.dragon.common.web.PageRequest;
import com.dragon.modules.yuegou.entity.system.RoleEntity;
import com.dragon.modules.yuegou.entity.system.UserEntity;
import com.dragon.modules.yuegou.entity.system.UserRoleRefEntity;
import com.dragon.modules.yuegou.enums.OwnerType;
import com.dragon.modules.yuegou.enums.code.SystemCode;
import com.dragon.modules.yuegou.enums.system.UserStatus;
import com.dragon.modules.yuegou.mapper.system.UserMapper;
import com.dragon.modules.yuegou.model.system.User;
import com.dragon.modules.yuegou.query.system.AccountQuery;
import com.dragon.modules.yuegou.query.system.UserQuery;
import com.dragon.modules.yuegou.query.system.UserRoleRefQuery;
import com.dragon.modules.yuegou.service.system.RoleService;
import com.dragon.modules.yuegou.service.system.UserRoleRefService;
import com.dragon.modules.yuegou.service.system.UserService;
import com.dragon.modules.yuegou.web.Check;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
/**
 * 系统用户表--- 这块包含登录大运营平台、集团版本、悦商惠版本等除C端会员的所有用户集合 服务实现
 *
 * @author pbuilder generated
 * @date 2019-03-15 15:37:59
 * @version 2.0
 */
@Slf4j
@Service("sysUserService")
public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity>
		implements UserService {

	@Override
	public User getGroupUserByUsername(String username) {
		return baseMapper.getGroupUserByUsername(username);
	}

	@Override
	public User getGroupUserByMobile(String mobile) {
		return baseMapper.getGroupUserByMobile(mobile);
	}

	@Override
	public User getPlatformUserByUsername(String username) {
		return baseMapper.getPlatformUserByUsername(username);
	}

	@Override
	public User getPlatformUserByMobile(String mobile) {
		return baseMapper.getPlatformUserByMobile(mobile);
	}

	@Override
	public User getMerchantUserByUsername(String username) {
		return baseMapper.getMerchantUserByUsername(username);
	}

	@Override
	public User getMerchantUserByMobile(String mobile) {
		return baseMapper.getMerchantUserByMobile(mobile);
	}

	@Override
	public Map<String, User> getByIds(Collection<String> ids) {
		if (ids.isEmpty()) {
			return Collections.emptyMap();
		}
		return listByIds(ids).stream().map(User::new).collect(Collectors.toMap(User::getId, UnaryOperator.identity()));
	}

	@Override
	public void bindCreator(User user) {
		String createdBy = user.getCreatedBy();
		UserEntity userEntity = this.getById(createdBy);
		if (userEntity != null) {
			user.setCreatedByName(user.getUsername());
		}
	}

	@Override
	public IPage<User> search(PageRequest page, AccountQuery query) {
		IPage<UserEntity> pageEntity = new Page<>(page.getPage(), page.getSize(), page.getCount());
		return userMapper.search(pageEntity, query);
	}

	@Override
	public IPage<User> searchGroup(PageRequest page, AccountQuery query) {
		IPage<UserEntity> pageEntity = new Page<>(page.getPage(), page.getSize(), page.getCount());
		return userMapper.searchGroup(pageEntity, query);
	}

	@Transactional
	@Override
	public void deleteAccount(String userId) {
		Check.notNull(userId, SystemCode.USERID_NOTNULL.getMessage());
		removeById(userId);
	}

	@Override
	public void enableUser(String userId) {
		Check.notEmpty(userId, SystemCode.USERID_NOTNULL.getMessage());
		User user = new User();
		user.setId(userId);
		user.setStatus(UserStatus.ENABLED);
		baseMapper.updateById(user);
	}

	@Override
	public void disableUser(String userId) {
		Check.notEmpty(userId, SystemCode.USERID_NOTNULL.getMessage());
		User user = new User();
		user.setId(userId);
		user.setStatus(UserStatus.DISABLED);
		baseMapper.updateById(user);
	}

	@Override
	public List<User> searchUser(String userInfo, String roleId) {
		Check.notNull(roleId, "角色Id不能为空");
		List<User> users = userMapper.searchUser(userInfo);
		List<User> roleUser = userMapper.roleUser(roleId);
		for (int i = 0; i < users.size(); i++) {
			User useri = users.get(i);
			for (int j = 0; j < roleUser.size(); j++) {
				User userj = roleUser.get(j);
				if (useri.getId().equals(userj.getId())) {
					users.remove(i);
					i--;
					break;
				}
			}
		}
		return users;
	}

	@Override
	public List<User> searchGroupUser(String userInfo,String groupId) {
		return userMapper.searchGroupUser(userInfo, groupId);
	}

	@Override
	public List<User> busdIdlistUser(String busdId, String username) {
		return userMapper.busdIdlistUser(busdId, username);
	}

	@Override
	public List<User> fileList(String contactMobile) {
		Check.notNull(contactMobile, SystemCode.MOBILE_NOTNULL.getMessage());
		UserQuery query = new UserQuery();
		query.setDel(false);
		query.setUsername(contactMobile);
		List<UserEntity> entities = list(query.toQueryWrapper());
		return entities.stream().map(User::new).collect(Collectors.toList());
	}

	@Override
	public Long countUser(String contactMobile) {
		Check.notNull(contactMobile, SystemCode.MOBILE_NOTNULL.getMessage());
		UserQuery query = new UserQuery();
		query.setDel(false);
		query.setUsername(contactMobile);
		return baseMapper.selectCount(query.toQueryWrapper());
	}

	@Override
	public User login(User user, String password) {
		if (user == null) {
			throw new DragonException(SystemCode.ACCOUNT_NOT_EXIT);
		}
		Check.notNull(user.getUsername(), SystemCode.ACCOUNT_NOTNULL.getMessage());
		Check.notNull(user.getPassword(), SystemCode.PASSWORD_NOTNULL.getMessage());
		if (!this.validatePwd(user, password)) {
			throw new DragonException(SystemCode.ACCOUNT_PASSWORD_IS_INCORRECT);
		}
		return user;
	}

	@Override
	public void loginByCode(String mobile, String code, String password) {
		Check.notNull(mobile, SystemCode.ACCOUNT_NOTNULL.getMessage());
		log.debug("验证账号验证码是否正确，开始==，账号={}", mobile);
		Check.notNull(code, "验证码不能为空");
		Check.notNull(password, SystemCode.PASSWORD_NOTNULL.getMessage());
		UserQuery userQuery = new UserQuery();
		userQuery.setDel(false);
		userQuery.setMobile(mobile);
		UserEntity user = baseMapper.selectOne(userQuery.toQueryWrapper());
		if (StringUtils.isEmpty(user.getId())) {
			log.info("验证账号是否正确，账号不正确，账号={}", mobile);
			throw new DragonException(SystemCode.ACCOUNT_PASSWORD_IS_INCORRECT);
		}
		String salt = RandomStringUtils.randomNumeric(3);
		String sign = DigestUtils.md5Hex(password + salt);
		user.setPassword(sign);
		baseMapper.updateById(user);
		log.info("验证账号验证码是否存在，账号验证码正确，账号={}", mobile);
	}

	@Override
	public User getPersonalInfo() {
		UserEntity userEntity = baseMapper.selectById("");
		UserRoleRefQuery query = new UserRoleRefQuery();
		query.setDel(false);
		query.setUserId(userEntity.getId());
		List<UserRoleRefEntity> list = userRoleRefService.list(query.toQueryWrapper());
		User user = new User(userEntity);
		for (UserRoleRefEntity userRoleRef : list) {
			RoleEntity role = roleService.getById(userRoleRef.getRoleId());
			user.setRoleName(role.getRoleName());
		}
		return user;
	}

	@Override
	public User getUserByGroupId(String groupId) {
		Check.notNull(groupId, "分组id不能为空");
		return null;
	}

	@Override
	public List<User> roleUser(String roleId) {
		Check.notNull(roleId, "角色id不能为空");
		return userMapper.roleUser(roleId);
	}

	@Override
	public User createAccount(String username, @Nullable String mobile, @Nullable String nickname, String password) {
		String salt = "";
		String pwd = "";	
		String id = null;
		Check.notNull(username, SystemCode.ACCOUNT_NOTNULL.getMessage());
		Check.length(username, 0, 20, "账号长度限制在0~20个字符");
		Check.notEmpty(password, SystemCode.PASSWORD_NOTNULL.getMessage());
		Check.length(password, 6, Integer.MAX_VALUE, SystemCode.PASSWORD_LENGTH.getMessage());
		salt = generateRandomSalt();
		pwd = digestPwd(password, salt);

		User user = new User();
		user.setId(id);
		user.setUsername(username);
		user.setMobile(mobile);
		user.setNickName(nickname);
		user.setStatus(UserStatus.ENABLED);
		user.setPassword(pwd);
		user.setSalt(salt);
		user.setDel(false);
		Long count = 0l;
		if (!StringUtils.isEmpty(id)){
			QueryWrapper<UserEntity> queryWrapper = new QueryWrapper<>();
			queryWrapper.eq(UserEntity.COL_ID,id);
			count = baseMapper.selectCount(queryWrapper);
		}
		if (count > 0){
			baseMapper.updateById(user);
		}else {
			baseMapper.insert(user);
		}
		return user;
	}

	@Override
	@Transactional
	public void changePwd(String userId, String oldPwd, String newPwd, OwnerType ownerType) {
		Check.notEmpty(userId, SystemCode.USERID_NOTNULL.getMessage());
		Check.notEmpty(oldPwd, "旧密码不能为空");
		Check.notEmpty(newPwd, "新密码不能为空");
		Check.length(newPwd, 6, Integer.MAX_VALUE, SystemCode.PASSWORD_LENGTH.getMessage());
		UserEntity user = baseMapper.selectById(userId);
		if (user.getDel()) {
			throw new DragonException(SystemCode.ACCOUNT_DELETED);
		}
		if (validatePwd(new User(user), oldPwd)) {
			changePwd(userId, newPwd,ownerType);
		} else {
			throw new DragonException(SystemCode.INVALID_PASSWORD);
		}
	}

	@Override
	public void changePwd(String userId, String newPwd,OwnerType ownerType) {
		Check.notEmpty(userId, SystemCode.USERID_NOTNULL.getMessage());
		Check.notEmpty(newPwd, "新密码不能为空");
		Check.length(newPwd, 6, Integer.MAX_VALUE, SystemCode.PASSWORD_LENGTH.getMessage());
		String salt = generateRandomSalt();
		String pwd = digestPwd(newPwd, salt);
		log.info("前端密码={},盐={},密码={}", newPwd, salt, pwd);
		User model = new User();
		model.setId(userId);
		model.setPassword(pwd);
		model.setSalt(salt);
		baseMapper.updateById(model);
	}

	@Override
	public void modifyUsername(String userId, String username) {
		Check.notEmpty(userId, SystemCode.USERID_NOTNULL.getMessage());
		Check.notEmpty(username, "必须提供用户账号");
		Check.length(username, 0, 20, "账号长度限制在0~20个字符");
		UserEntity user = baseMapper.selectById(userId);
		if (username.equals(user.getUsername())) {
			return;
		}

		UserQuery userQuery = new UserQuery();
		userQuery.setUsername(username);
		userQuery.setDel(false);
		if (count(userQuery.toQueryWrapper()) > 0) {
			throw new DragonException(SystemCode.ACCOUNT_EXISTS);
		}
		User model = new User();
		model.setId(userId);
		model.setUsername(username);
		// XXX 账号是账号，手机号是手机号，请区分
		model.setMobile(username);
		baseMapper.updateById(user);
	}

	/**
	 * 生成随机salt
	 * 
	 * @return salt
	 */
	private String generateRandomSalt() {
		return RandomStringUtils.randomAlphabetic(2);
	}

	/**
	 * 密码签名
	 * 
	 * @param pwd
	 *            密码
	 * @param salt
	 *            盐
	 * @return 密码+盐的签名
	 */
	private String digestPwd(String pwd, String salt) {
		return DigestUtils.md5Hex(pwd + salt);
	}

	/**
	 * 验证用户密码
	 * 
	 * @param user
	 *            用户
	 * @param pwd
	 *            外部提供的密码
	 * @return true表示密码验证通过，false表示密码错误
	 */
	private boolean validatePwd(User user, String pwd) {
		String salt = user.getSalt();
		String hash = digestPwd(pwd, salt);
		return hash.equals(user.getPassword());
	}

	@Autowired
	private UserMapper userMapper;

	@Autowired
	private UserRoleRefService userRoleRefService;

	@Autowired
	private RoleService roleService;
}